Makefile: add PyPI publish and release targets#20
Conversation
There was a problem hiding this comment.
Pull request overview
Adds release-oriented Makefile targets to build and publish the Python package via Poetry, including PyPI publishing and GitHub release creation, with version derived from pyproject.toml.
Changes:
- Extract package version in Makefile for use in release/publish commands.
- Add
build,publish-dry-run,publish, andclean-disttargets. - Update
cleanto also removedist/artifacts.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Makefile
Outdated
| VERSION := $(shell \ | ||
| grep '^version' pyproject.toml | head -1 | \ | ||
| sed 's/.*"\(.*\)"/\1/') |
There was a problem hiding this comment.
VERSION is extracted by grepping/parsing pyproject.toml, which is brittle (format changes, whitespace, switching between [tool.poetry] vs PEP 621 [project], etc.). Since this Makefile already depends on Poetry, prefer deriving the version via poetry version -s (or a small python -c using tomllib) so the value matches what Poetry will actually build/publish.
| VERSION := $(shell \ | |
| grep '^version' pyproject.toml | head -1 | \ | |
| sed 's/.*"\(.*\)"/\1/') | |
| VERSION := $(shell poetry version -s) |
| @echo "Would create GitHub release: v$(VERSION)" | ||
| @echo "Package contents:" | ||
| @ls -lh dist/ | ||
| poetry publish --dry-run |
There was a problem hiding this comment.
publish-dry-run depends on build, but poetry publish --dry-run will typically build again unless --no-build is provided. Consider adding --no-build here to avoid redundant builds and ensure the dry-run output reflects the artifacts currently in dist/.
| poetry publish --dry-run | |
| poetry publish --dry-run --no-build |
| .PHONY: publish | ||
| publish: build ## Publish to PyPI, tag and create GitHub release | ||
| poetry publish | ||
| git tag -a "v$(VERSION)" -m "Release v$(VERSION)" | ||
| git push origin "v$(VERSION)" | ||
| gh release create "v$(VERSION)" dist/* \ | ||
| --title "v$(VERSION)" \ | ||
| --notes "Release v$(VERSION)" |
There was a problem hiding this comment.
publish depends on build, but poetry publish will typically rebuild unless --no-build is used. Adding --no-build makes the target faster and ensures the PyPI upload and the dist/* artifacts attached to the GitHub release are based on the same already-built output.
| poetry publish | ||
| git tag -a "v$(VERSION)" -m "Release v$(VERSION)" | ||
| git push origin "v$(VERSION)" | ||
| gh release create "v$(VERSION)" dist/* \ |
There was a problem hiding this comment.
As written, poetry publish happens before any checks that the git tag can be created/pushed or that gh is authenticated. If the tag already exists (or gh release create fails), you can end up with a PyPI release without the corresponding tag/GitHub release. Consider adding preflight checks (e.g., fail if tag v$(VERSION) exists, ensure clean working tree, verify gh auth status) before publishing so failures happen before the irreversible step.
eafa464 to
2ce3743
Compare
Summary
make buildto build the package with Poetrymake publish-dry-runto preview what would be publishedmake publishto publish to PyPI, create a git tag (vX.Y.Z), and create a GitHub release with the dist artifactsmake clean-distto clean distribution artifactspyproject.tomlTest plan
make publish-dry-runand verify it shows version, tag, and package contents without side effectsmake buildand verifydist/contains the expected.tar.gzand.whlfiles